﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
 

namespace UpgadeFileCombineApp
{
    public partial class HexFile
    {
       
        public Byte[] AppImage;

        public HexFile(string filename)
        {
            try
            {
                FileInfo inf = new FileInfo(filename);
                if (inf.Exists)
                {
                    AppImage = ParseFile(filename);   //解析文件
                }
                else
                {
                    throw new Exception("文件未找到!");
                }
            }

            catch
            {
                throw new Exception(".hex文件不存在或文件错误!");

            }
        }

        static byte[] StrToHexByte(string hexString)
        {
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

        static byte[] FFToHexByte(int fflen)
        {
            byte[] returnBytes = new byte[fflen];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = 0xFF;
            return returnBytes;
        }

        public List<byte> ListByteImage = new List<byte>();

        private byte[] ParseFile(string szHexPath)
        {
            try
            {
                Int32 i;
                Int32 j = 0;
                String szTxt = "";   //合并HEX文件的数据
                String szLine = "";  //Hex文件每行的数据
                //String szHex = "";   //bin文件的HEX字符串数据
                int startAdr = 0;    //起始地址
                int endAdr = 0;      //用于判断hex地址是否连续，不连续补充0xFF
                int lineLenth;       //当前行的数据长度
                bool FirstLineFlag;  //起始行标志位
                bool FirstAddrFlag;  //起始地址标志位
                int ff_len;

                StreamReader HexReader = new StreamReader(szHexPath);
                FirstLineFlag = true;
                FirstAddrFlag = true;
                while ((szLine = HexReader.ReadLine()) != null)
                {
                    if (szLine.Substring(0, 1) == ":") //判断首字符是”:”
                    {
                        if (szLine.Substring(7, 2) == "00")//数据记录
                        {

                            lineLenth = Int32.Parse(szLine.Substring(1, 2), System.Globalization.NumberStyles.HexNumber); // 获取一行的数据个数值
                            startAdr = Int32.Parse(szLine.Substring(3, 4), System.Globalization.NumberStyles.HexNumber); // 获取地址值
                            if (FirstAddrFlag)
                            {
                                endAdr = startAdr;
                                FirstAddrFlag = false;
                            }

                            //地址有空白,填FF
                            ff_len = startAdr - endAdr;
                            if (ff_len > 0)
                            {
                                byte[] ffdata = FFToHexByte(ff_len);
                                ListByteImage.AddRange(ffdata);  //空白部分补FF
                            }

                            byte[] newdata = StrToHexByte(szLine.Substring(9, lineLenth * 2));
                            ListByteImage.AddRange(newdata);

                            endAdr = startAdr + lineLenth;
                        }
                        else if (szLine.Substring(7, 2) == "04")//起始标识
                        {
                            if (FirstLineFlag)
                            {
                                FirstLineFlag = false;
                            }
                        }
                        else
                        {
                        }
                    }
                }
                HexReader.Close(); //关闭目标文件

                byte[] szBin = ListByteImage.ToArray();
                return szBin;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return null;
            }

        }

    }
}
